package cn.iocoder.yudao.module.pay.wallet.dal.mysql;


import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.pay.wallet.dal.dataobject.PayWalletDO;
import cn.iocoder.yudao.module.pay.wallet.vo.PayWalletPageReqVO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;

@SuppressWarnings("UnusedReturnValue")
@Mapper
public interface PayWalletMapper extends CoreMapper<PayWalletDO> {

    default PayWalletDO selectByUserIdAndType(Long userId, Integer userType) {
        return selectOne(PayWalletDO::getUserId, userId,
                PayWalletDO::getUserType, userType);
    }

    default PageResult<PayWalletDO> selectPage(PayWalletPageReqVO reqVO) {
        return selectPage(reqVO, new CoreLambdaQueryWrapper<PayWalletDO>()
                .eqIfPresent(PayWalletDO::getUserId, reqVO.getUserId())
                .eqIfPresent(PayWalletDO::getUserType, reqVO.getUserType())
                .betweenIfPresent(PayWalletDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(PayWalletDO::getId));
    }

    /**
     * 当消费退款时候， 更新钱包
     *
     * @param id 钱包 id
     * @param price 消费金额，只能为正数
     */
    default int updateWhenConsumptionRefund(Long id, Integer price) {
        price = Math.abs(price); //防止恶意传入负数
        LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
                .setSql(" balance = balance + " + price
                        + ", total_expense = total_expense - " + price)
                .eq(PayWalletDO::getId, id);
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 当消费时候， 更新钱包
     *
     * @param price 消费金额
     * @param id 钱包 id，只能为正数
     */
    default int updateWhenConsumption(Long id, Integer price) {
        price = Math.abs(price); //防止恶意传入负数
        LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
                .setSql(" balance = balance - " + price
                        + ", total_expense = total_expense + " + price)
                .eq(PayWalletDO::getId, id)
                .ge(PayWalletDO::getBalance, price); // cas 逻辑
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 当充值的时候，更新钱包
     *
     * @param id 钱包 id
     * @param price 钱包金额，只能为正数
     */
    default int updateWhenRecharge(Long id, Integer price) {
        price = Math.abs(price); //防止恶意传入负数
        LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
                .setSql(" balance = balance + " + price
                        + ", total_recharge = total_recharge + " + price)
                .eq(PayWalletDO::getId, id);
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 提现余额的时候，更新钱包
     *
     * @param id 钱包 id
     * @param price 提现金额，负数表示返还
     */
    default int updateWhenCashOut(Long id, Integer price) {
        LambdaUpdateWrapper<PayWalletDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql(" balance = balance - " + price
                       + ", money = money - " + price
                       + ", money_cashing = money_cashing + " + price);
        wrapper.eq(PayWalletDO::getId, id);
        if (price > 0) {
            wrapper.ge(PayWalletDO::getMoney, price); // cas 逻辑
        } else {
            wrapper.ge(PayWalletDO::getMoneyCashing, Math.abs(price)); // cas 逻辑
        }
        return update(null, wrapper);
    }


    /**
     * 更新可提现余额
     *
     * @param id 钱包 id
     * @param price 佣金，负数表示返还
     */
    default int updateMoney(Long id, Integer price) {
        LambdaUpdateWrapper<PayWalletDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql(" balance = balance + " + price
                       + ", money = money + " + price);
        wrapper.eq(PayWalletDO::getId, id);
        return update(null, wrapper);
    }

    /**
     * 更新不可提现余额
     *
     * @param id 钱包 id
     * @param price 钱包金额，负数表示减少
     */
    default int updateBalance(Long id, Integer price) {
        LambdaUpdateWrapper<PayWalletDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.setSql(" balance = balance + " + price);
        wrapper.eq(PayWalletDO::getId, id);
        if (price < 0) {
            wrapper.ge(PayWalletDO::getBalance, Math.abs(price)); // cas 逻辑
        }
        return update(null, wrapper);
    }

    /**
     * 冻结钱包部分余额
     *
     * @param id 钱包 id
     * @param price 冻结金额，只能是正数
     */
    default int freezePrice(Long id, Integer price) {
        price = Math.abs(price); //防止恶意传入负数
        LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
                .setSql(" balance = balance - " + price
                        + ", freeze_price = freeze_price + " + price)
                .eq(PayWalletDO::getId, id)
                .ge(PayWalletDO::getBalance, price); // cas 逻辑
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 解冻钱包余额
     *
     * @param id 钱包 id
     * @param price 解冻金额，只能是正数
     */
    default int unfreezePrice(Long id, Integer price) {
        price = Math.abs(price); //防止恶意传入负数
        LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
                .setSql(" balance = balance + " + price
                        + ", freeze_price = freeze_price - " + price)
                .eq(PayWalletDO::getId, id)
                .ge(PayWalletDO::getFreezePrice, price); // cas 逻辑
        return update(null, lambdaUpdateWrapper);
    }

    /**
     * 当充值退款时, 更新钱包
     *
     * @param id 钱包 id
     * @param price 退款金额，只能是正数
     */
    default int updateWhenRechargeRefund(Long id, Integer price) {
        price = Math.abs(price); //防止恶意传入负数
        LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
                .setSql(" freeze_price = freeze_price - " + price
                        + ", total_recharge = total_recharge - " + price)
                .eq(PayWalletDO::getId, id)
                .ge(PayWalletDO::getFreezePrice, price)
                .ge(PayWalletDO::getTotalRecharge, price);// cas 逻辑
        return update(null, lambdaUpdateWrapper);
    }


}




